#include <gtest/gtest.h>
#include <gflags/gflags.h>
#include <boost/date_time/posix_time/posix_time.hpp>

#include "channel.hpp"
#include "etcd.hpp"     //服务注册
#include <thread>
#include <vector>
#include "utils.hpp"

#include "message.pb.h"
#include "base.pb.h"
#include "file.pb.h"
#include "user.pb.h"

DEFINE_bool(run_mode, false, "程序的运行模式, fasle-调试; true-发布;");
DEFINE_string(log_file, "", "发布模式下, 用于指定日志的输出文件");
DEFINE_int32(log_level, 0, "发布模式下, 用于指定日志输出等级");  //trace default 0

DEFINE_string(etcd_host, "http://127.0.0.1:2379", "这是服务中心地址");
DEFINE_string(base_service, "/service", "服务监控根目录");
DEFINE_string(message_service, "/service/message_service", "服务监控目录");

//21df-12664a1c-0000 张三三三 f7aa-b126b9c7-0001张三
auto service_manager = std::make_shared<xchat::ServiceManager>();

void range_test(const std::string &ssid, boost::posix_time::ptime &start_time, boost::posix_time::ptime &end_time)
{
    auto channel = service_manager->choose(FLAGS_message_service);
    ASSERT_TRUE(channel != nullptr);
    xchat::MsgStorageService_Stub stub(channel.get());
    xchat::GetHistoryMsgReq req;
    
    req.set_request_id(xchat::uuid());
    req.set_chat_session_id(ssid);
    req.set_start_time(boost::posix_time::to_time_t(start_time));
    req.set_over_time(boost::posix_time::to_time_t(end_time));

    std::unique_ptr<xchat::GetHistoryMsgRsp> rsp(new xchat::GetHistoryMsgRsp());
    std::unique_ptr<brpc::Controller> cntl(new brpc::Controller());
    stub.GetHistoryMsg(cntl.get(), &req, rsp.get(), nullptr); // 同步调用
    ASSERT_FALSE(cntl->Failed());
    ASSERT_TRUE(rsp->success());

    for(int i = 0; i < rsp->msg_list_size(); i++)
    {
        std::cout << "--------------------------------------------" << std::endl;
        auto msg = rsp->msg_list(i);
        std::cout << "msg_id: " << msg.message_id() << std::endl;
        std::cout << "msg_chat_session_id: " << msg.chat_session_id() << std::endl;
        std::cout << "msg_timestamp: " << boost::posix_time::to_simple_string(boost::posix_time::from_time_t(msg.timestamp())) << std::endl;
        std::cout << "user_id: " << msg.sender().user_id() << std::endl;
        std::cout << "nickname: " << msg.sender().nickname() << std::endl;
        std::cout << "avatar: " << msg.sender().avatar() << std::endl;
        if(msg.message().message_type() == xchat::MessageType::STRING)
        {
            std::cout << "文本消息: " << msg.message().string_message().content() << std::endl;
        }
        else if(msg.message().message_type() == xchat::MessageType::IMAGE)
        {
            std::cout << "图片消息ID: " << msg.message().image_message().file_id() << std::endl;
            std::cout << "图片消息内容: " << msg.message().image_message().image_content() << std::endl;
        }
        else if(msg.message().message_type() == xchat::MessageType::FILE)
        {
            std::cout << "文件消息ID: " << msg.message().file_message().file_id() << std::endl;
            std::cout << "文件消息文件名: " << msg.message().file_message().file_name() << std::endl;
            std::cout << "文件消息文件大小: " << msg.message().file_message().file_size() << std::endl;
            std::cout << "文件消息内容: " << msg.message().file_message().file_contents() << std::endl;
        }
        else if(msg.message().message_type() == xchat::MessageType::SPEECH)
        {
            std::cout << "语音消息ID: " << msg.message().speech_message().file_id() << std::endl;
            std::cout << "语音消息文件名: " << msg.message().speech_message().file_contents() << std::endl;
        }
        else
        {
            std::cout << "未知消息类型" << std::endl;
            abort();
        }
    }
}

void recent_test(const std::string &ssid, int64_t count)
{
    auto channel = service_manager->choose(FLAGS_message_service);
    ASSERT_TRUE(channel != nullptr);
    xchat::MsgStorageService_Stub stub(channel.get());
    xchat::GetRecentMsgReq req;
    
    req.set_request_id(xchat::uuid());
    req.set_chat_session_id(ssid);
    req.set_msg_count(count);
   
    std::unique_ptr<xchat::GetRecentMsgRsp> rsp(new xchat::GetRecentMsgRsp());
    std::unique_ptr<brpc::Controller> cntl(new brpc::Controller());
    stub.GetRecentMsg(cntl.get(), &req, rsp.get(), nullptr); // 同步调用
    ASSERT_FALSE(cntl->Failed());
    ASSERT_TRUE(rsp->success());

    for(int i = 0; i < rsp->msg_list_size(); i++)
    {
        std::cout << "--------------------------------------------" << std::endl;
        auto msg = rsp->msg_list(i);
        std::cout << "msg_id: " << msg.message_id() << std::endl;
        std::cout << "msg_chat_session_id: " << msg.chat_session_id() << std::endl;
        std::cout << "msg_timestamp: " << boost::posix_time::to_simple_string(boost::posix_time::from_time_t(msg.timestamp())) << std::endl;
        std::cout << "user_id: " << msg.sender().user_id() << std::endl;
        std::cout << "nickname: " << msg.sender().nickname() << std::endl;
        std::cout << "avatar: " << msg.sender().avatar() << std::endl;
        if(msg.message().message_type() == xchat::MessageType::STRING)
        {
            std::cout << "文本消息: " << msg.message().string_message().content() << std::endl;
        }
        else if(msg.message().message_type() == xchat::MessageType::IMAGE)
        {
            std::cout << "图片消息ID: " << msg.message().image_message().file_id() << std::endl;
            std::cout << "图片消息内容: " << msg.message().image_message().image_content() << std::endl;
        }
        else if(msg.message().message_type() == xchat::MessageType::FILE)
        {
            std::cout << "文件消息ID: " << msg.message().file_message().file_id() << std::endl;
            std::cout << "文件消息文件名: " << msg.message().file_message().file_name() << std::endl;
            std::cout << "文件消息文件大小: " << msg.message().file_message().file_size() << std::endl;
            std::cout << "文件消息内容: " << msg.message().file_message().file_contents() << std::endl;
        }
        else if(msg.message().message_type() == xchat::MessageType::SPEECH)
        {
            std::cout << "语音消息ID: " << msg.message().speech_message().file_id() << std::endl;
            std::cout << "语音消息文件名: " << msg.message().speech_message().file_contents() << std::endl;
        }
        else
        {
            std::cout << "未知消息类型" << std::endl;
            abort();
        }
    }

}

void search_test(const std::string &ssid, const std::string &key)
{
    auto channel = service_manager->choose(FLAGS_message_service);
    ASSERT_TRUE(channel != nullptr);
    xchat::MsgStorageService_Stub stub(channel.get());
    xchat::MsgSearchReq req;
    
    req.set_request_id(xchat::uuid());
    req.set_chat_session_id(ssid);
    req.set_search_key(key);
   
    std::unique_ptr<xchat::MsgSearchRsp> rsp(new xchat::MsgSearchRsp());
    std::unique_ptr<brpc::Controller> cntl(new brpc::Controller());
    stub.MsgSearch(cntl.get(), &req, rsp.get(), nullptr); // 同步调用
    ASSERT_FALSE(cntl->Failed());
    ASSERT_TRUE(rsp->success());

    for(int i = 0; i < rsp->msg_list_size(); i++)
    {
        std::cout << "--------------------------------------------" << std::endl;
        auto msg = rsp->msg_list(i);
        std::cout << "msg_id:                " << msg.message_id() << std::endl;
        std::cout << "msg_chat_session_id:   " << msg.chat_session_id() << std::endl;
        std::cout << "msg_timestamp:         " << boost::posix_time::to_simple_string(boost::posix_time::from_time_t(msg.timestamp())) << std::endl;
        std::cout << "user_id:               " << msg.sender().user_id() << std::endl;
        std::cout << "nickname:              " << msg.sender().nickname() << std::endl;
        std::cout << "avatar:                " << msg.sender().avatar() << std::endl;
        if(msg.message().message_type() == xchat::MessageType::STRING)
        {
            std::cout << "文本消息:             " << msg.message().string_message().content() << std::endl;
        }
        else if(msg.message().message_type() == xchat::MessageType::IMAGE)
        {
            std::cout << "图片消息ID:           " << msg.message().image_message().file_id() << std::endl;
            std::cout << "图片消息内容:         " << msg.message().image_message().image_content() << std::endl;
        }
        else if(msg.message().message_type() == xchat::MessageType::FILE)
        {
            std::cout << "文件消息ID:            " << msg.message().file_message().file_id() << std::endl;
            std::cout << "文件消息文件名:        " << msg.message().file_message().file_name() << std::endl;
            std::cout << "文件消息文件大小:      " << msg.message().file_message().file_size() << std::endl;
            std::cout << "文件消息内容:          " << msg.message().file_message().file_contents() << std::endl;
        }
        else if(msg.message().message_type() == xchat::MessageType::SPEECH)
        {
            std::cout << "语音消息ID:           " << msg.message().speech_message().file_id() << std::endl;
            std::cout << "语音消息文件名:       " << msg.message().speech_message().file_contents() << std::endl;
        }
        else
        {
            std::cout << "未知消息类型" << std::endl;
            abort();
        }
    }

}

int main(int argc, char* argv[])
{
    google::ParseCommandLineFlags(&argc, &argv, true);
    
    xchat::init_logger(FLAGS_run_mode, FLAGS_log_file, FLAGS_log_level);


    //1.先构造Rpc信道管理对象
    service_manager->declared(FLAGS_message_service);
    auto put_cb = std::bind(&xchat::ServiceManager::onServiceOnline, service_manager.get(), std::placeholders::_1, std::placeholders::_2);
    auto del_cb = std::bind(&xchat::ServiceManager::onServiceOffline, service_manager.get(), std::placeholders::_1, std::placeholders::_2);
    //2.构造服务发现对象
    xchat::Discovery::ptr dclient = std::make_shared<xchat::Discovery>(FLAGS_etcd_host, FLAGS_base_service, put_cb, del_cb);

    boost::posix_time::ptime start_time = boost::posix_time::time_from_string("2025-09-30 10:00:00");
    boost::posix_time::ptime end_time = boost::posix_time::time_from_string("2025-09-30 15:00:00");
    int64_t count = 3;
    range_test("会话ID1", start_time, end_time);
    std::cout << "-----------------" << std::endl;
    recent_test("会话ID1", count);
    std::cout << "--------should1---------" << std::endl;
    search_test("会话ID1", "盖浇");
    std::cout << "--------should2---------" << std::endl;
    search_test("会话ID1", "盖浇饭");

    return 0;
}